#include<iostream>
#include<memory>
#include<string>
//简单工厂模式
// class Fruit
// {
//     public:
//     virtual void show() =0;

// };

// class Apple: public Fruit
// {
//     void show() override
//     {
//         std::cout<<"我是苹果\n";
//     }
// };

// class Banana: public Fruit
// {
//     void show() override
//     {
//         std::cout<<"我是香蕉\n";
//     }
// };

// class FruitFactory
// {
//     public: 
//     static std::shared_ptr<Fruit> Create(const std::string& name)
//     {
//         if(name=="苹果")
//         {
//             return std::make_shared<Apple>();
//         }
//         else
//         {
//             return std::make_shared<Banana>();
//         }
//     }

// };
// int main()
// {
//     std::shared_ptr<Fruit> sptr=FruitFactory::Create("苹果");
//     sptr->show();
//     std::shared_ptr<Fruit> sptr1=FruitFactory::Create("香蕉");
//     sptr1->show();
//     return 0;
// }

//工厂方法模式  一种产品一个工厂

// class Fruit
// {
//     public:
//     Fruit(){}
//     virtual void show() =0;
// };

// class Apple: public Fruit
// {
//     public:

//     void show() override
//     {
//         std::cout<<"我是苹果\n";
//     }
// };

// class Banana: public Fruit
// {
//     public:
//     void show() override
//     {
//         std::cout<<"我是香蕉\n";
//     }
// };

// class FruitFactory
// {
//     public:
//     virtual std::shared_ptr<Fruit> create()=0;
// };

// class AppleFactory: public FruitFactory
// {
//     public:
//     std::shared_ptr<Fruit> create() override
//     {
//         return std::make_shared<Apple>();
//     }
// };
// class BananaFactory: public FruitFactory
// {
//     public:
//     std::shared_ptr<Fruit> create() override
//     {
//         return std::make_shared<Banana>();
//     }
// };

// int main()
// {
//     std::shared_ptr<FruitFactory> factory(new AppleFactory());
//     auto fruit = factory->create();
//     fruit->show();
//     factory.reset(new BananaFactory());
//     fruit = factory->create();
//     fruit->show();
//  return 0;
// }

//抽象工厂模式

class Fruit
{
    public:
    virtual void name()=0;
};

class Apple: public Fruit
{
    public:
    void name() override
    {
        std::cout<<"我是一个苹果!!\n";
    }
};
class Banana: public Fruit
{
    public:
    void name() override
    {
        std::cout<<"我是一个香蕉!!\n";
    }
};

class Animal
{
    public:
    virtual void name()=0;
};

class Lamp: public Animal
{
    public:
    void name() override
    {
        std::cout<<"我是一只山羊!!\n";
    }
};

class Dog: public Animal
{
    public:
    void name() override
    {
        std::cout<<"我是一只小狗!!\n";
    }
};

class Factory
{
    public:
    virtual std::shared_ptr<Fruit> GetFruit(const std::string& name)=0;
    virtual std::shared_ptr<Animal> GetAnimal(const std::string& name)=0;
};

class FruitFactory:public Factory
{
    public:
    std::shared_ptr<Fruit> GetFruit(const std::string& name) override
    {
        if(name=="苹果")
        {
            return std::make_shared<Apple>();
        }
        else if(name=="香蕉")
        {
            return std::make_shared<Banana>();
        }

        return std::shared_ptr<Fruit>();
    }
    std::shared_ptr<Animal> GetAnimal(const std::string& name) override
    {
        return std::shared_ptr<Animal>();
    }
};

class AnimalFactory:public Factory
{
    public:
    std::shared_ptr<Fruit> GetFruit(const std::string& name) override
    {
        return std::shared_ptr<Fruit>();
    }
    std::shared_ptr<Animal> GetAnimal(const std::string& name) override
    {
         if(name=="小狗")
        {
            return std::make_shared<Dog>();
        }
        else if(name=="山羊")
        {
            return std::make_shared<Lamp>();
        }

        return std::shared_ptr<Animal>();
    }
};

class FactoryProducer
{
    public:
    static std::shared_ptr<Factory> Create(const std::string& name)
    {
        if(name=="水果")
        {
            return std::make_shared<FruitFactory>();
        }
        else if(name=="动物")
        {
            return std::make_shared<AnimalFactory>();
        }
        return std::shared_ptr  <Factory>();
    }

};

int main()
{
    std::shared_ptr<Factory> ff=FactoryProducer::Create("水果");
    auto fruit=ff->GetFruit("苹果");
    fruit->name();
    fruit=ff->GetFruit("香蕉");
    fruit->name();

    std::shared_ptr<Factory> af=FactoryProducer::Create("动物");
    auto animal=af->GetAnimal("小狗");
    animal->name();
    animal=af->GetAnimal("山羊");
    animal->name();
    
    return 0;
}